package com.codedancer.campus.client.service.impl;

import com.codedancer.campus.client.service.ISmsService;
import com.codedancer.campus.client.service.bo.sms.SendSmsBo;
import com.codedancer.campus.common.config.SmsConfig;
import com.codedancer.campus.common.exception.BusinessException;
import com.codedancer.campus.common.utils.RedisUtil;
import com.codedancer.campus.common.utils.VerificationCodeUtil;
import com.codedancer.campus.enums.SendPhoneType;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException;
import java.io.IOException;
import java.util.ArrayList;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class SmsServiceImpl implements ISmsService {

    @Autowired
    private SmsSingleSender smsSingleSender;
    @Autowired
    private SmsConfig smsConfig;
    @Autowired
    private RedisUtil redisUtil;
    // 手机号注册验证码key
    @Value("${start.campus.redis.login.phone.key}")
    private String loginCodeKey;
    // 手机号修改验证码key
    @Value("${start.campus.redis.update.phone.key}")
    private String updateCodeKey;
    // 验证码redisTemplate
    @Resource(name = "smsRedisTemplate")
    private StringRedisTemplate smsRedisTemplate;
    // 手机号注册模板id
    private static final Integer REGISTER_TEMPLATE_ID = 1581873;
    // 手机号修改模板id
    private static final Integer UPDATE_TEMPLATE_ID = 1611994;

    /**
     * 发送短信(可以考虑优化成工厂模式)
     *
     * @param sendSmsBo
     */
    @Override
    public void sendSms(SendSmsBo sendSmsBo) throws HTTPException, IOException {
        redisUtil.setRedisTemplate(smsRedisTemplate);
        // 判断发送类型
        if (sendSmsBo.getType().equals(SendPhoneType.REGISTER_PHONE.getValue())) {
            // 注册短信发送
            sendLoginCode(sendSmsBo.getPhone());
        }
        if (sendSmsBo.getType().equals(SendPhoneType.UPDATE_PHONE.getValue())) {
            // 修改手机号发送
            sendUpdateCode(sendSmsBo.getPhone());
        }
    }

    /**
     * 发送登录手机验证码
     *
     * @param phone
     */
    private void sendLoginCode(String phone) {
        // 先判断该手机号是否已被发送短信
        if (redisUtil.isExist(loginCodeKey + phone)) {
            log.info("该手机号已发送短信");
            throw new BusinessException("验证码发送频繁，稍后再试");
        }
        // 生成6位验证码
        String code = VerificationCodeUtil.getSixCode();
        // 发送短信
        ArrayList<String> params = new ArrayList<>();
        params.add(code);
        params.add("5");
        try {
            SmsSingleSenderResult smsSingleSenderResult = smsSingleSender
                .sendWithParam("86", phone, REGISTER_TEMPLATE_ID, params,
                    smsConfig.getSigncontent(), "", "");
            if (smsSingleSenderResult.result == 0 && "OK".equals(smsSingleSenderResult.errMsg)) {
                log.info("登录手机短信发送成功，手机号：{}", phone);
                // 保存到Redis中,设置时间为5分钟
                redisUtil.setStringValueAndTime(loginCodeKey + phone, code, 300L);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送修改手机验证码
     *
     * @param phone
     */
    private void sendUpdateCode(String phone) {
        // 先判断该手机号是否已被发送短信
        if (redisUtil.isExist(updateCodeKey + phone)) {
            log.info("该手机号已发送短信");
            throw new BusinessException("验证码发送频繁，稍后再试");
        }
        // 生成6位验证码
        String code = VerificationCodeUtil.getSixCode();
        // 发送短信
        ArrayList<String> params = new ArrayList<>();
        params.add(code);
        try {
            SmsSingleSenderResult smsSingleSenderResult = smsSingleSender
                .sendWithParam("86", phone, UPDATE_TEMPLATE_ID, params,
                    smsConfig.getSigncontent(), "", "");
            if (smsSingleSenderResult.result == 0 && "OK".equals(smsSingleSenderResult.errMsg)) {
                log.info("修改手机短信发送成功，手机号：{}", phone);
                // 保存到Redis中,设置时间为5分钟
                redisUtil.setStringValueAndTime(updateCodeKey + phone, code, 300L);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
